/**
 * @author 2019/7/22 10:30 by 刘赵强
 **/

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 模拟数据导入，不需要关注导入结果
 * 普通循环=======1545
 * 线程池循环耗时=======313
 */
public class BatchImportThread {
    public int dataSize = 50;

    public static void main(String[] args) {
        BatchImportThread batchImportThread = new BatchImportThread();
        batchImportThread.doImport();
        batchImportThread.doImportByThread();
    }

    public void doImport() {
        try {
            //模拟导入订单数据
            final List<Integer> dataList = this.getDataList();
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < dataSize; i++) {
                //模拟做一条数据导入到数据库花费的时间
                Thread.sleep(30);
                System.out.print(dataList.get(i)+">");
            }
            System.out.println();
            System.out.println("普通循环=======" + (System.currentTimeMillis() - startTime));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void doImportByThread() {
        try {
            //模拟导入订单数据
            final List<Integer> dataList = this.getDataList();
            //拆分成多个任务，每个任务包含step条数据
            int step = 10;
            int totalTasks = (dataList.size() % step == 0 ? dataList.size() / step : (dataList.size() / step + 1));
            System.out.println("totalTasks = "+totalTasks);
            final CountDownLatch countDownLatch = new CountDownLatch(totalTasks);
            long startTime1 = System.currentTimeMillis();
            //线程数量对程序耗时有不同影响
            ExecutorService executorService = Executors.newFixedThreadPool(15);
            List<Integer> list = new CopyOnWriteArrayList<>();
//            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int j = 0; j < dataList.size(); j = j + step) {
                final int start = j;
                final int perCount = (dataList.size() - start) < step ? (dataList.size() - start) : step;
                executorService.execute(() -> {
                    try {
                        for (int n = 0; n < perCount; n++) {
                            list.add(dataList.get(start + n));
                            //模拟做一条数据导入到数据库花费的时间
                            Thread.sleep(30);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        countDownLatch.countDown();
                    }
                });
            }
            countDownLatch.await();
            System.out.println();
            System.out.println("线程池循环耗时=======" + (System.currentTimeMillis() - startTime1));
            executorService.shutdown();
            list.sort(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1-o2;
                }
            });
            for (Integer integer :list){
                System.out.println(integer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 模拟导入数据
     */
    public List<Integer> getDataList() {
        //模拟导入数据
        final List<Integer> dataList = new ArrayList<>();
        for (int i = 0; i < dataSize; i++) {
            dataList.add(i);
        }
        return dataList;
    }
}

